// LISP 语言唯一的语法就是括号要配对。

// 形如 (OP P1 P2 …)，括号内元素由单个空格分割。

// 其中第一个元素 OP 为操作符，后续元素均为其参数，参数个数取决于操作符类型。

// 注意：

// 参数 P1, P2 也有可能是另外一个嵌套的 (OP P1 P2 …) ，

// 当前 OP 类型为 add / sub / mul / div（全小写），分别代表整数的加减乘除法，

// 简单起见，所有 OP 参数个数均为 2 。

// 举例:

// 输入：(mul 3 -7)

// 输出：21

// 输入：(add 1 2)

// 输出：3

// 输入：(sub (mul 2 4) (div 9 3))

// 输出：5

// 输入：(div 1 0)

// 输出：error

// 题目涉及数字均为整数，可能为负；

// 不考虑 32 位溢出翻转，计算过程中也不会发生 32 位溢出翻转，

// 除零错误时，输出 “error”，

// 除法遇除不尽，向下取整，即 3/2 = 1
// (sub (mul 2 4) (div 9 3))
// 5
function lispCount(str) {
    let total = 0;
    let stack = [];
    let numberStack = [];
    const countMap = {
        's': "sub",
        'm': "mul",
        'a': 'add',
        'd': 'div'
    }
    const count = (a, b, type) => {
        if (type === 'sub') {
            return a - b
        } else if (type === 'mul') {
            return a * b
        } else if (type === 'div') {
            if (b === 0) {
                return 'error'
            }
            return a / b
        } else if (type === 'add') {
            return a + b
        }
    }
    for (let i = 0; i < str.length; i++) {
        if (str[i] === '(' || str[i] === ' ') {
        } else if (countMap[str[i]]) {
            stack.push(countMap[str[i]]);
            i += 2
        } else if (/\d+/.test(str[i]) || str[i] === '-') {
            let sub = str[i]
            while (str[i + 1] && /\d+/.test(str[i + 1])) {
                sub += str[i + 1];
                i++
            }
            numberStack.push(sub)
        } else if (str[i] === ')') {
            let mathType = stack.pop();
            let b = parseInt(numberStack.pop());
            let a = parseInt(numberStack.pop());
            let r = count(a, b, mathType);
            if (r === 'error') {
                console.log('error');
                return;
            }
            if (i === str.length - 1) {
                console.log(count(a, b, mathType))
            } else {
                numberStack.push(r)
            }
        }
    }
}
lispCount('(sub (mul 12 4) (div 24 3))')
lispCount('(mul 3 -7)')
lispCount('(add 1 2)')
lispCount('(div 1 0)')
lispCount('(div 12 (sub 45 45))')
// lispCount('(sub (mul 2 4) (div 9 3))')